﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Threading;

namespace ConsoleApplication1
{
    public class Puffer
    {

// ---------------------------------------------- Deklaration der Variablen ----------------------------------------------

        private List<String>[] messageArray; // Ringpuffer mit 5 
        private Connector connector;
        private Parser parser;

        private static int maxContent = 50;
        public int schreiber = 0;
        int leser = 0;

        //public int emptycount = maxContent;
        //public int fillcount = 0;

// --------------------------------------------- Konstruktor Initialisierung ---------------------------------------------

       /*
        * Konstruktor des Puffers
        * 
        * @param
        */
        public Puffer(Connector connector)
        {
            this.connector = connector;
            messageArray = new List<string>[maxContent];
            this.parser = new Parser(this);
            Thread parserThread = new Thread(new ThreadStart(parser.ReadFromPuffer));
            parserThread.Start();
        }


// ------------------------------------------------ öffentliche Methoden -------------------------------------------------

        /*
         * Methode zur Abfrage ob der Puffer leer ist.
         * @return true bei leerem Puffer
         */
        public bool IsEmpty()
        {
            bool empty = true;
            for (int i = 0; i < maxContent; i++)
            {
                if (messageArray[i] != null)
                    empty = false;
            }
                return empty;
        }

        /*
         * Methode zur Abfrage ob der Puffer voll ist.
         * @return true bei vollem Puffer
         */
        public bool IsFull()
        {
            bool full = true;
            for (int i = 0; i < maxContent; i++)
            {
                if (messageArray[i] == null)
                    full = false;
            }
            return full;
        }



        /*
         * Methode zum befüllen des Puffers
         * @param element  String-Liste als Arrayelemente
         */
        public void EnqueueMessage(List<String> element)
        {
            try
            {
                if (element == null)
                {
                    Console.WriteLine("NullElement kann nicht in Puffer geschrieben werden!");
                    throw new Exception("Element ist NULL");
                }

                if (this.messageArray[schreiber] != null)
                {
                    Console.WriteLine("Puffer ist voll. Fehler beim Speichern neuer Servernachricht!");
                    throw new Exception("Puffer ist voll. Fehler beim Speichern neuer Servernachricht!");
                }
                else
                {
                    this.messageArray[schreiber] = new List<string>(element);
                    this.schreiber = schreiber + 1;
                    if (this.schreiber == this.messageArray.Length)
                    {
                        this.schreiber = 0;
                    }
                }
            }
            catch (Exception e)
            {
                e.ToString(); 
                
            }
        }



        /*
         * Methode zur Ausgabe des als nächstes zu behandelnden
         * Pufferelements
         * @return gibt eine String-Liste zurück
         */
        public List<String> PopMessage()
        {
            List<String> list = null;
            try
            {
                if (this.messageArray[this.leser] == null)
                {
                    throw new Exception("Puffer enthält momentan keine Nachrichten!");
                }
                else
                {
                    list = this.messageArray[this.leser];
                    this.messageArray[this.leser] = null;
                    this.leser = leser + 1;
                    if (this.leser == this.messageArray.Length)
                    {
                        this.leser = 0;
                    }
                }      
            } catch(Exception e) {
                e.ToString();
            }
            return list;
        }





 // ----------------------------------------------- Getter/Setter-Methoden -----------------------------------------------

        /*
         * Getter-Methode für den Puffer-Array
         * @return gibt den gesamten Puffer zurück
         */ 
        public List<String>[] MessageArray
        {
            get 
            { 
                return this.messageArray;
            }
        }


        /*
         * Getter/Setter-Methode für den Connector 
         * @return gibt den Connector zurück falls vorhanden
         */
        public Connector Connector
        {
            get
            {
                return connector;
            }
            set
            {
                this.connector = value;
            }
        }


        /*
         * Getter/Setter-Methode für den Parser
         * @return gibt den Parser zurück falls vorhanden 
         */

        public Parser Parser
        {
            get
            {
                return parser;
            }
            set
            {
                this.parser = value;
            }
        }
    }
}
